/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Server;

import Login.UserManagement;
import dataserver.DataServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.logging.Logger;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.LoggerFactory;

/**
 *
 * @author bambo_000
 */
public class MinaTest {

    /**
     * @param args the command line arguments
     */
    private static final int PORT = 9123;
    
    public static void main(String[] args) throws IOException {
        final org.slf4j.Logger logger = LoggerFactory.getLogger(MinaTest.class);
        // TODO code application logic here
        IoAcceptor acceptor = new NioSocketAcceptor();

        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
//        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( 
//                new TextLineCodecFactory( Charset.forName( "UTF-8" ))));  
        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                new TextLineCodecFactory(Charset.forName("UTF-8"),
                LineDelimiter.WINDOWS.getValue(),
                LineDelimiter.WINDOWS.getValue())));
        
        acceptor.setHandler(  new ServerHandler() ); 
        
        acceptor.getSessionConfig().setReadBufferSize( 2048 );
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
        
        acceptor.bind( new InetSocketAddress(PORT) );
    }
    
}

class ServerHandler extends IoHandlerAdapter
{
    @Override
    public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
    {
        cause.printStackTrace();
    }
    
    @Override
    public void messageReceived( IoSession session, Object message ) throws Exception
    {
        String tempStr = message.toString();
        String[] result = tempStr.split(";", 4);

        //System.out.println(result[1]+"    " + result[2]);
        
        switch (result[0]) {
            case "Query" :
                queryHandler (session,result[1],result[2],result[3]);
                //session.close(true);
                break;   
            case "Update":
                updateHandler(session,result[1],result[2],result[3]);
                break;
            case "Runway":
                session.write("Runway");
                System.out.println("Send Runway State to " + session.getRemoteAddress());
                break;
            case "Flight":
//                tempResults = ds.getCommand("Query","flight","All","Flight='"+result[1]+"'");
//                System.out.println(tempResults);     
//                
//                if ( tempResults.length()>0 ) {
//                    session.write( tempResults );
//                } else {
//                    session.write( "-1" );
//                    System.out.println("Null flight!!");
//                }     
//                session.close(true);
                break;   
            case "quit":
                session.close(true);
                return;
        }
        session.close(true);
        //session.write( "Server has got the info!!" );
        System.out.println("Message written...");
    }
    
    @Override
    public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
    {
        System.out.println( "IDLE " + session.getIdleCount( status ));
    }
    
    void queryHandler (IoSession session,String typeName, String var1, String var2) {
        DataServer ds = new DataServer();
        ds.getConnection();
        String tempResults = null;
        
        switch (typeName) {
            case "Login" :
                tempResults = ds.getCommand("Query","user","Salt,Status","Username='"+var1+"'");
                //String tempResult = new UserManagement().validateUser(result[1], result[2]);
                if (tempResults.length()>0) {
                    String tempStr = tempResults;
                    String[] result = tempStr.split(",", 2);
                    
                    // user is online
                    if (result[1].equals("online")) {
                        session.write( "online" );
                        System.out.println("Username is online!");
                    } else {
                        if (UserManagement.MD5(var2+result[0]).equals(
                                ds.getCommand("Query", "shadow", "HashPassword", 
                                              "Username='"+var1+"'"))) {
                            session.write("true");
                            
                            // update user status
                            updateHandler(session,"Login",var1,"online");
                        } else {
                            session.write("false");
                        } 
                    }
                } else {
                    session.write( "false" );
                    System.out.println("Username and password is uncorrect!");
                }     
                //session.close(true);
                break;   
            case "Weather":
                tempResults = ds.getCommand("Query","weathercurrent","All","id='1'");
                session.write(tempResults);
                break;
            case "Runway":
                tempResults = ds.getCommand("Query","runwaysstatus","All","id='1'") + ";";
                tempResults += ds.getCommand("Query","runwaysstatus","All","id='2'");
                session.write(tempResults);
                break;
            case "Flight":
                tempResults = ds.getCommand("Query","flight","All","Flight='"+var1+"'");
                System.out.println(tempResults);     
                
                if ( tempResults.length()>0 ) {
                    session.write( tempResults );
                } else {
                    session.write( "-1" );
                    System.out.println("Null flight!!");
                }     
                break;   
            case "quit":

                return;
        }
    }
    
    void updateHandler (IoSession session,String typeName, String var1, String var2) {
        DataServer ds = new DataServer();
        ds.getConnection();
        String tempResults = null;
        
        switch (typeName) {
            case "Login" :
                if (var2.equals("online")) {
                    System.out.println(ds.getCommand("Update","user","Status='online'","Username='"+var1+"'")); 
                } else {
                    System.out.println(ds.getCommand("Update","user","Status='offline'","Username='"+var1+"'")); 
                }    
                break;   
            default:
                return;
        }
    }
}


